{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 首先 import 必要的模块\n",
    "import pandas as pd \n",
    "import numpy as np\n",
    "\n",
    "from sklearn.model_selection import GridSearchCV\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Pregnancies</th>\n",
       "      <th>Glucose</th>\n",
       "      <th>BloodPressure</th>\n",
       "      <th>SkinThickness</th>\n",
       "      <th>Insulin</th>\n",
       "      <th>BMI</th>\n",
       "      <th>DiabetesPedigreeFunction</th>\n",
       "      <th>Age</th>\n",
       "      <th>SkinThickness_Missing</th>\n",
       "      <th>Outcome</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>0</td>\n",
       "      <td>0.529395</td>\n",
       "      <td>0.866045</td>\n",
       "      <td>-0.031990</td>\n",
       "      <td>0.670643</td>\n",
       "      <td>-0.181541</td>\n",
       "      <td>0.166619</td>\n",
       "      <td>0.468492</td>\n",
       "      <td>1.425995</td>\n",
       "      <td>-0.647760</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1</td>\n",
       "      <td>-1.149280</td>\n",
       "      <td>-1.205066</td>\n",
       "      <td>-0.528319</td>\n",
       "      <td>-0.012301</td>\n",
       "      <td>-0.181541</td>\n",
       "      <td>-0.852200</td>\n",
       "      <td>-0.365061</td>\n",
       "      <td>-0.190672</td>\n",
       "      <td>-0.647760</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>2</td>\n",
       "      <td>1.200864</td>\n",
       "      <td>2.016662</td>\n",
       "      <td>-0.693761</td>\n",
       "      <td>-0.012301</td>\n",
       "      <td>-0.181541</td>\n",
       "      <td>-1.332500</td>\n",
       "      <td>0.604397</td>\n",
       "      <td>-0.105584</td>\n",
       "      <td>1.543781</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>3</td>\n",
       "      <td>-1.149280</td>\n",
       "      <td>-1.073567</td>\n",
       "      <td>-0.528319</td>\n",
       "      <td>-0.695245</td>\n",
       "      <td>-0.540642</td>\n",
       "      <td>-0.633881</td>\n",
       "      <td>-0.920763</td>\n",
       "      <td>-1.041549</td>\n",
       "      <td>-0.647760</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>4</td>\n",
       "      <td>-0.142075</td>\n",
       "      <td>0.504422</td>\n",
       "      <td>-2.679076</td>\n",
       "      <td>0.670643</td>\n",
       "      <td>0.316566</td>\n",
       "      <td>1.549303</td>\n",
       "      <td>5.484909</td>\n",
       "      <td>-0.020496</td>\n",
       "      <td>-0.647760</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   Pregnancies   Glucose  BloodPressure  SkinThickness   Insulin       BMI  \\\n",
       "0     0.529395  0.866045      -0.031990       0.670643 -0.181541  0.166619   \n",
       "1    -1.149280 -1.205066      -0.528319      -0.012301 -0.181541 -0.852200   \n",
       "2     1.200864  2.016662      -0.693761      -0.012301 -0.181541 -1.332500   \n",
       "3    -1.149280 -1.073567      -0.528319      -0.695245 -0.540642 -0.633881   \n",
       "4    -0.142075  0.504422      -2.679076       0.670643  0.316566  1.549303   \n",
       "\n",
       "   DiabetesPedigreeFunction       Age  SkinThickness_Missing  Outcome  \n",
       "0                  0.468492  1.425995              -0.647760        1  \n",
       "1                 -0.365061 -0.190672              -0.647760        0  \n",
       "2                  0.604397 -0.105584               1.543781        1  \n",
       "3                 -0.920763 -1.041549              -0.647760        0  \n",
       "4                  5.484909 -0.020496              -0.647760        1  "
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 读取数据\n",
    "# 请自行在log(x+1)特征和tf_idf特征上尝试，并比较不同特征的结果，\n",
    "# path to where the data lies\n",
    "train = pd.read_csv('FE_pima-indians-diabetes.csv')\n",
    "train.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_train = train['Outcome']   \n",
    "X_train = train.drop([\"Outcome\"], axis=1)\n",
    "\n",
    "#保存特征名字以备后用（可视化）\n",
    "feat_names = X_train.columns \n",
    "\n",
    "#sklearn的学习器大多之一稀疏数据输入，模型训练会快很多\n",
    "#查看一个学习器是否支持稀疏数据，可以看fit函数是否支持: X: {array-like, sparse matrix}.\n",
    "#可自行用timeit比较稠密数据和稀疏数据的训练时间\n",
    "from scipy.sparse import csr_matrix\n",
    "X_train = csr_matrix(X_train)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Logistic Regression + GridSearchCV\n",
    "## log似然损失"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "logistic回归的需要调整超参数有：C（正则系数，一般在log域（取log后的值）均匀设置候选参数）和正则函数penalty（L2/L1） \n",
    "目标函数为：J =  C* sum(logloss(f(xi), yi)) + penalty \n",
    "\n",
    "在sklearn框架下，不同学习器的参数调整步骤相同：\n",
    "1. 设置参数搜索范围\n",
    "2. 生成学习器实例（参数设置）\n",
    "3. 生成GridSearchCV的实例（参数设置）\n",
    "4. 调用GridSearchCV的fit方法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "GridSearchCV(cv=5, error_score='raise-deprecating',\n",
       "             estimator=LogisticRegression(C=1.0, class_weight=None, dual=False,\n",
       "                                          fit_intercept=True,\n",
       "                                          intercept_scaling=1, l1_ratio=None,\n",
       "                                          max_iter=100, multi_class='warn',\n",
       "                                          n_jobs=None, penalty='l2',\n",
       "                                          random_state=None, solver='liblinear',\n",
       "                                          tol=0.0001, verbose=0,\n",
       "                                          warm_start=False),\n",
       "             iid='warn', n_jobs=None,\n",
       "             param_grid={'C': [0.1, 1, 10, 100, 1000], 'penalty': ['l1', 'l2']},\n",
       "             pre_dispatch='2*n_jobs', refit=True, return_train_score=True,\n",
       "             scoring='neg_log_loss', verbose=0)"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.model_selection import GridSearchCV\n",
    "from sklearn.linear_model import LogisticRegression\n",
    "\n",
    "#需要调优的参数\n",
    "# 请尝试将L1正则和L2正则分开，并配合合适的优化求解算法（slover）\n",
    "#tuned_parameters = {'penalty':['l1','l2'],\n",
    "#                   'C': [0.001, 0.01, 0.1, 1, 10, 100, 1000]\n",
    "#                   }\n",
    "penaltys = ['l1','l2']\n",
    "Cs = [ 0.1, 1, 10, 100, 1000]\n",
    "tuned_parameters = dict(penalty = penaltys, C = Cs)\n",
    "\n",
    "lr_penalty= LogisticRegression(solver='liblinear')\n",
    "grid= GridSearchCV(lr_penalty, tuned_parameters,cv=5, scoring='neg_log_loss', return_train_score=True)\n",
    "grid.fit(X_train,y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.47447825085928286\n",
      "{'C': 1, 'penalty': 'l1'}\n"
     ]
    }
   ],
   "source": [
    "# examine the best model\n",
    "print(-grid.best_score_)\n",
    "print(grid.best_params_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# plot CV误差曲线\n",
    "test_means = grid.cv_results_[ 'mean_test_score' ]\n",
    "test_stds = grid.cv_results_[ 'std_test_score' ]\n",
    "train_means = grid.cv_results_[ 'mean_train_score' ]\n",
    "train_stds = grid.cv_results_[ 'std_train_score' ]\n",
    "\n",
    "# plot results\n",
    "n_Cs = len(Cs)\n",
    "number_penaltys = len(penaltys)\n",
    "test_scores = np.array(test_means).reshape(n_Cs,number_penaltys)\n",
    "train_scores = np.array(train_means).reshape(n_Cs,number_penaltys)\n",
    "test_stds = np.array(test_stds).reshape(n_Cs,number_penaltys)\n",
    "train_stds = np.array(train_stds).reshape(n_Cs,number_penaltys)\n",
    "\n",
    "x_axis = np.log10(Cs)\n",
    "for i, value in enumerate(penaltys):\n",
    "    #pyplot.plot(log(Cs), test_scores[i], label= 'penalty:'   + str(value))\n",
    "    plt.errorbar(x_axis, -test_scores[:,i], yerr=test_stds[:,i] ,label = penaltys[i] +' Test')\n",
    "    plt.errorbar(x_axis, -train_scores[:,i], yerr=train_stds[:,i] ,label = penaltys[i] +' Train')\n",
    "    \n",
    "plt.legend()\n",
    "plt.xlabel( 'log(C)' )                                                                                                      \n",
    "plt.ylabel( 'logloss' )\n",
    "plt.savefig('LogisticGridSearchCV_C.png' )\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 正确率"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "GridSearchCV(cv=5, error_score='raise-deprecating',\n",
       "             estimator=LogisticRegression(C=1.0, class_weight=None, dual=False,\n",
       "                                          fit_intercept=True,\n",
       "                                          intercept_scaling=1, l1_ratio=None,\n",
       "                                          max_iter=100, multi_class='warn',\n",
       "                                          n_jobs=None, penalty='l2',\n",
       "                                          random_state=None, solver='liblinear',\n",
       "                                          tol=0.0001, verbose=0,\n",
       "                                          warm_start=False),\n",
       "             iid='warn', n_jobs=None,\n",
       "             param_grid={'C': [0.1, 1, 10, 100, 1000], 'penalty': ['l1', 'l2']},\n",
       "             pre_dispatch='2*n_jobs', refit=True, return_train_score=True,\n",
       "             scoring='accuracy', verbose=0)"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.model_selection import GridSearchCV\n",
    "from sklearn.linear_model import LogisticRegression\n",
    "\n",
    "#需要调优的参数\n",
    "# 请尝试将L1正则和L2正则分开，并配合合适的优化求解算法（slover）\n",
    "#tuned_parameters = {'penalty':['l1','l2'],\n",
    "#                   'C': [0.001, 0.01, 0.1, 1, 10, 100, 1000]\n",
    "#                   }\n",
    "penaltys = ['l1','l2']\n",
    "Cs = [ 0.1, 1, 10, 100, 1000]\n",
    "tuned_parameters = dict(penalty = penaltys, C = Cs)\n",
    "\n",
    "lr_penalty= LogisticRegression(solver='liblinear')\n",
    "grid= GridSearchCV(lr_penalty, tuned_parameters,cv=5, scoring='accuracy', return_train_score=True)\n",
    "grid.fit(X_train,y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "-0.7760416666666666\n",
      "{'C': 1, 'penalty': 'l1'}\n"
     ]
    }
   ],
   "source": [
    "# examine the best model\n",
    "print(-grid.best_score_)\n",
    "print(grid.best_params_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# plot CV误差曲线\n",
    "test_means = grid.cv_results_[ 'mean_test_score' ]\n",
    "test_stds = grid.cv_results_[ 'std_test_score' ]\n",
    "train_means = grid.cv_results_[ 'mean_train_score' ]\n",
    "train_stds = grid.cv_results_[ 'std_train_score' ]\n",
    "\n",
    "# plot results\n",
    "n_Cs = len(Cs)\n",
    "number_penaltys = len(penaltys)\n",
    "test_scores = np.array(test_means).reshape(n_Cs,number_penaltys)\n",
    "train_scores = np.array(train_means).reshape(n_Cs,number_penaltys)\n",
    "test_stds = np.array(test_stds).reshape(n_Cs,number_penaltys)\n",
    "train_stds = np.array(train_stds).reshape(n_Cs,number_penaltys)\n",
    "\n",
    "x_axis = np.log10(Cs)\n",
    "for i, value in enumerate(penaltys):\n",
    "    #pyplot.plot(log(Cs), test_scores[i], label= 'penalty:'   + str(value))\n",
    "    plt.errorbar(x_axis, -test_scores[:,i], yerr=test_stds[:,i] ,label = penaltys[i] +' Test')\n",
    "    plt.errorbar(x_axis, -train_scores[:,i], yerr=train_stds[:,i] ,label = penaltys[i] +' Train')\n",
    "    \n",
    "plt.legend()\n",
    "plt.xlabel( 'log(C)' )                                                                                                      \n",
    "plt.ylabel( 'logloss' )\n",
    "plt.savefig('LogisticGridSearchCV_C.png' )\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
